package com.run.cat.common.util;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;

public abstract class QrCreate {

	 /** 日期格式：yyyy-MM-dd HH:mm:ss */
	 public static String DF_DATETIME = "yyyyMMdd";
	 private static float alpha = 1f;
	 private static final int BLACK = 0xFF000000;// 用于设置图案的颜色

	 private static final int WHITE = 0xFFFFFFFF; // 用于背景色

	 /**
	  *
	  * @Title: toBufferedImage
	  * @Description: 把文本转化成二维码图片对象
	  * @param text
	  *   二维码内容
	  * @param width
	  *   二维码高度
	  * @param height
	  *   二位宽度
	  *   设定文件
	  * @return BufferedImage 返回类型
	  * @throws
	  */
	 public static BufferedImage toBufferedImage(String text, int width, int height) throws Exception {
		  int BLACK = 0xFF000000;
		  int WHITE = 0xFFFFFFFF;
		  Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
		  hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); // 内容所使用字符集编码
		  hints.put(EncodeHintType.MARGIN, 1);
		  BitMatrix matrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height, hints);
		  BufferedImage image = new BufferedImage(width, height,
		    BufferedImage.TYPE_INT_RGB);
		  for (int x = 0; x < width; x++) {
		   for (int y = 0; y < height; y++) {
		    image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
		   }
		  }
		  return image;
	 }

	 /**
	  *
	  * @Title: markImageByCode
	  * @Description: 向图片指定位置增加二维码
	  * @param img
	  *   二维码image对象
	  * @param srcImgPath
	  *   背景图
	  * @param targerPath
	  *   目标图
	  * @param positionWidth
	  *   位置横坐标
	  * @param positionHeight
	  *   位置纵坐标
	  * @return void 返回类型
	  * @throws
	  */
	 public static void markImageByCode(Image img, String srcImgPath,
	    String targerPath, int positionWidth, int positionHeight) {
	    OutputStream os = null;
	    try {

		   Image srcImg = ImageIO.read(new File(srcImgPath));

		   BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),
		     srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);

		   // 1、得到画笔对象
		   Graphics2D g = buffImg.createGraphics();

		   // 2、设置对线段的锯齿状边缘处理
		   g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

		   g.drawImage(
		     srcImg.getScaledInstance(srcImg.getWidth(null),
		       srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0,
		     null);

		   g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
		     alpha));

		   // 3、二维码位置
		   g.drawImage(img, positionWidth, positionHeight, null);
		   g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
		   // 4、释放资源
		   g.dispose();

		   // 5、生成图片（建议生成PNG的，jpg会失真）
		   os = new FileOutputStream(targerPath);
		   ImageIO.write(buffImg, "PNG", os);

		   System.out.println("二维码图片生成成功");

		  } catch (Exception e) {
			  e.printStackTrace();
		  } finally {
			   try {
			    if (null != os)
			     os.close();
			   } catch (Exception e) {
			    e.printStackTrace();
			   }
		  }
	 }

	 /**
	  *
	  * @Title: pressText
	  * @Description:向图片指定位置加上文字
	  * @param pressText
	  *   文字内容
	  * @param srcImageFile
	  *   原图片
	  * @param destImageFile
	  *   目标图片
	  * @param x
	  *   横坐标
	  * @param y
	  *   纵坐标
	  * @param alpha
	  *   透明度
	  * @return void 返回类型
	  * @throws
	  */
	 public final static void pressText(String pressText, String srcImageFile,
	   String destImageFile, int x, int y, float alpha) {
	   try {
		   File img = new File(srcImageFile);
		   Image src = ImageIO.read(img);
		   int width = src.getWidth(null);
		   int height = src.getHeight(null);
		   BufferedImage image = new BufferedImage(width, height,
		     BufferedImage.TYPE_INT_RGB);
		   Graphics2D g = image.createGraphics();
		   // 开文字抗锯齿 去文字毛刺
		   g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
		     RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
		   g.drawImage(src, 0, 0, width, height, null);
		   // 设置颜色
		   g.setColor(new Color(89, 87, 87));
		   // 设置 Font
		   g.setFont(new Font("方正兰亭中黑_GBK", Font.BOLD, 14));
		   g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
		     alpha));
		   // 第一参数->设置的内容，后面两个参数->文字在图片上的坐标位置(x,y) .
		   g.drawString(pressText, x, y);
		   g.dispose();
		   ImageIO.write((BufferedImage) image, "PNG", new File(destImageFile));// 输出到文件流
	   } catch (Exception e) {
		   e.printStackTrace();
	   }
	 }


	 public static boolean createQrCode(OutputStream outputStream, String content, int qrCodeSize, String imageFormat) throws WriterException, IOException{
            //设置二维码纠错级别ＭＡＰ
            Hashtable<EncodeHintType, ErrorCorrectionLevel> hintMap = new Hashtable<EncodeHintType, ErrorCorrectionLevel>();
            hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);  // 矫错级别
            QRCodeWriter qrCodeWriter = new QRCodeWriter();
            //创建比特矩阵(位矩阵)的QR码编码的字符串
            BitMatrix byteMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, qrCodeSize, qrCodeSize, hintMap);
            // 使BufferedImage勾画QRCode  (matrixWidth 是行二维码像素点)
            int matrixWidth = byteMatrix.getWidth();
            BufferedImage image = new BufferedImage(matrixWidth-200, matrixWidth-200, BufferedImage.TYPE_INT_RGB);
            image.createGraphics();
            Graphics2D graphics = (Graphics2D) image.getGraphics();
            graphics.setColor(Color.WHITE);
            graphics.fillRect(0, 0, matrixWidth, matrixWidth);
            // 使用比特矩阵画并保存图像
            graphics.setColor(Color.BLACK);
            for (int i = 0; i < matrixWidth; i++){
                for (int j = 0; j < matrixWidth; j++){
                    if (byteMatrix.get(i, j)){
                        graphics.fillRect(i-100, j-100, 1, 1);
                    }
                }
            }
            return ImageIO.write(image, imageFormat, outputStream);
    }

	 // 日期转字符串

	 /** 将日期格式化为String，默认格式为yyyy-MM-dd HH:mm:ss，默认日期为当前日期. */
	 public static String toStr() {
	  return toStr(DF_DATETIME);
	 }

	 /** 将日期格式化为String，格式由参数format指定，默认日期为当前日期，format值可使用本类常量或自定义. */
	 public static String toStr(String format) {
	  return toStr(format, new Date());
	 }

	 /** 将日期格式化为String，默认格式为yyyy-MM-dd HH:mm:ss，日期由参数date指定. */
	 public static String toStr(Date date) {
	  return toStr(DF_DATETIME, date);
	 }

	 /** 将日期格式化为String，格式由参数format指定，日期由参数date指定，format值可使用本类常量或自定义. */
	 public static String toStr(String format, Date date) {
	  return new SimpleDateFormat(format).format(date);
	 }

	 public static String formateNumber(int num) {
	  DecimalFormat df = new DecimalFormat("000000");
	  String str2 = df.format(num);
	  return str2;
	 }

	 public static boolean makeDirs(String filePath) {

	  File folder = new File(filePath);
	  return (folder.exists() && folder.isDirectory()) ? true : folder
	    .mkdirs();
	 }


	    /**
	     * 生成二维码
	     *
	     * @param content    二维码内容
	     * @param outPutFile 二维码输出文件
	     * @return
	     * @throws IOException
	     * @throws WriterException
	     * @author raozj  v1.0   2018年3月13日
	     */
	    public static boolean generateQRImage(String content, String outPutFile) throws IOException, WriterException {
	        int width = 300; // 二维码图片宽度 300
	        int height = 300; // 二维码图片高度300

	        String format = "png";// 二维码的图片格式 png

	        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();

	        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);// 指定纠错等级,纠错级别（L 7%、M 15%、Q 25%、H 30%）
	        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");// 内容所使用字符集编码
	        hints.put(EncodeHintType.MARGIN, 1);// 设置二维码边的空度，非负数

	        BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);

	        String path = outPutFile.substring(0, outPutFile.lastIndexOf("/"));
	        File pathFile = new File(path);
	        if (!pathFile.exists()) {
	            pathFile.mkdirs();
	        }

	        // 生成二维码
	        File outputFile = new File(outPutFile);// 指定输出路径
	        BufferedImage image = toBufferedImage(bitMatrix);

	        if (!ImageIO.write(image, format, outputFile)) {
	            return false;
	        } else {
	            return true;
	        }
	    }

	    public static BufferedImage toBufferedImage(BitMatrix matrix) {
	        int width = matrix.getWidth();
	        int height = matrix.getHeight();
	        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
	        for (int x = 0; x < width; x++) {
	            for (int y = 0; y < height; y++) {
	                if (x >= width / 5 * 2 && x <= width / 5 * 3) {
	                    if (y >= height / 5 * 2 && y <= height / 5 * 3) {
	                        image.setRGB(x, y, WHITE);
	                        continue;
	                    }
	                }
	                image.setRGB(x, y, (matrix.get(x, y) ? BLACK : WHITE));
	                // image.setRGB(x, y, (matrix.get(x, y) ? Color.YELLOW.getRGB()
	                // : Color.CYAN.getRGB()));
	            }
	        }
	        return image;
	    }

	    /**
	     * 设置 logo
	     *
	     * @param matrixImage 源二维码图片
	     * @return 返回带有logo的二维码图片
	     * @throws IOException
	     * @author Administrator sangwenhao
	     */
	    public static void logoMatrix(BufferedImage matrixImage, String logoFile) throws IOException {
	        /**
	         * 读取二维码图片，并构建绘图对象
	         */
	        Graphics2D g2 = matrixImage.createGraphics();

	        int matrixWidth = matrixImage.getWidth();
	        int matrixHeigh = matrixImage.getHeight();

	        /**
	         * 读取Logo图片
	         */
	        BufferedImage logo = ImageIO.read(new File(logoFile));

	        // 开始绘制图片
	        g2.drawImage(logo, matrixWidth / 5 * 2, matrixHeigh / 5 * 2, matrixWidth / 5, matrixHeigh / 5, null);// 绘制
	        BasicStroke stroke = new BasicStroke(5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
	        g2.setStroke(stroke);// 设置笔画对象
	        // 指定弧度的圆角矩形
	        RoundRectangle2D.Float round = new RoundRectangle2D.Float(matrixWidth / 5 * 2, matrixHeigh / 5 * 2,
	                matrixWidth / 5, matrixHeigh / 5, 20, 20);
	        g2.setColor(Color.white);
	        g2.draw(round);// 绘制圆弧矩形

	        // 设置logo 有一道灰色边框
	        BasicStroke stroke2 = new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
	        g2.setStroke(stroke2);// 设置笔画对象
	        RoundRectangle2D.Float round2 = new RoundRectangle2D.Float(matrixWidth / 5 * 2 + 2, matrixHeigh / 5 * 2 + 2,
	                matrixWidth / 5 - 4, matrixHeigh / 5 - 4, 20, 20);
	        g2.setColor(new Color(128, 128, 128));
	        g2.draw(round2);// 绘制圆弧矩形

	        g2.dispose();
	        matrixImage.flush();
	}
}
